﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Microsoft.Xna.Framework.Input;

namespace NapazEngine.Utilities.Data
{
    /// <summary>
    /// This class handles the loading and unloading of game controls and settings
    /// </summary>
    public class FileHandler
    {
        public FileHandler()
        {
            //TODO: Add logging
        }

        #region Settings Handling
        /// <summary>
        /// This method will save the settings to disk into
        /// a "settings.cfg" file
        /// </summary>
        /// <param name="settings">Settings instance to save</param>
        public void SaveSettings(Settings settings)
        {
            FileStream fs = new FileStream("settings.cfg", FileMode.Create);

            // Construct a BinaryFormatter and use it to serialize the data to the stream. 
            BinaryFormatter formatter = new BinaryFormatter();
            try
            {
                formatter.Serialize(fs, settings);
                fs.Flush();
                fs.Close();

                //log the output
                Global.GameLog.Log.Add("Successfully saved settings");
            }
            catch (SerializationException e)
            {
                Global.GameLog.Log.Add("Failed to serialize. Reason: " + e.Message);
                throw;
            }
            finally
            {
                fs.Close();
            }
        }

        /// <summary>
        /// Loads a Settings instance for the game.
        /// </summary>
        /// <returns>Settings - new settings instance</returns>
        public Settings LoadSettings()
        {
            try
            {
                Stream streamRead = File.OpenRead("settings.cfg");
                BinaryFormatter binaryRead = new BinaryFormatter();
                Settings newSettings = (Settings)binaryRead.Deserialize(streamRead);
                streamRead.Close();

                //log the settings saved
                Global.GameLog.Log.Add("Successfully loaded settings");

                return newSettings;
            }
            catch (Exception e)
            {
                //output log info
                Global.GameLog.Log.Add(e.StackTrace);
                Global.GameLog.Log.Add("Settings now found: Creating default settings file");

                //create new instance and save it
                Settings instance = new Settings();
                SaveSettings(instance);

                //return the instance
                return instance;
            }
        }
        #endregion


        #region Controls Handling
        /// <summary>
        /// Saves the controls that are passed in to be saved to disk.
        /// </summary>
        /// <param name="controls">Controls to save</param>
        public void SaveControls(Dictionary<PlayerAction, Keys> controls)
        {
            FileStream fs = new FileStream("controls.cfg", FileMode.Create);

            // Construct a BinaryFormatter and use it to serialize the data to the stream. 
            BinaryFormatter formatter = new BinaryFormatter();
            try
            {
                formatter.Serialize(fs, controls);
                fs.Flush();
                fs.Close();

                Global.GameLog.Log.Add("Successfully saved controls");
            }
            catch (SerializationException e)
            {
                Global.GameLog.Log.Add("Failed to serialize. Reason: " + e.Message);
                throw;
            }
            finally
            {
                fs.Close();
            }
        }

        /// <summary>
        /// Loads the controls from the hard drive
        /// </summary>
        /// <returns>Dictionary<CapstoneGame.GameScreen.actions, Keys> instance which 
        /// contains the saved controls.</returns>
        public Dictionary<PlayerAction, Keys> LoadControls()
        {
            try
            {
                Stream streamRead = File.OpenRead("controls.cfg");
                BinaryFormatter binaryRead = new BinaryFormatter();
                Dictionary<PlayerAction, Keys> controls = (Dictionary<PlayerAction, Keys>)binaryRead.Deserialize(streamRead);
                streamRead.Close();

                Global.GameLog.Log.Add("Successfully loaded controls");

                return controls;
            }
            catch (Exception e)
            {
                //output log info
                Global.GameLog.Log.Add(e.StackTrace);

                //no file found, create new instance
                Dictionary<PlayerAction, Keys> controls = new Dictionary<PlayerAction, Keys>();
                controls.Add(PlayerAction.MoveUp, Defaults.DEFAULT_MOVE_UP_KEY);
                controls.Add(PlayerAction.MoveDown, Defaults.DEFAULT_MOVE_DOWN_KEY);
                controls.Add(PlayerAction.MoveLeft, Defaults.DEFAULT_MOVE_LEFT_KEY);
                controls.Add(PlayerAction.MoveRight, Defaults.DEFAULT_MOVE_RIGHT_KEY);
                controls.Add(PlayerAction.Jump, Defaults.DEFAULT_JUMP_KEY);
                controls.Add(PlayerAction.Shoot, Defaults.DEFAULT_SHOOT_KEY);
                controls.Add(PlayerAction.Quit, Defaults.DEFAULT_QUIT_KEY);

                //return the instance
                return controls;
            }
        }
        #endregion
    }
}